www.gusucode.com > VC++ 酒店管理系统-源码程序 > VC++ 酒店管理系统-源码程序/code/hotel2003/CoolTabCtrl.cpp

    //Download by http://www.NewXing.com
/*####################################################################
	Filename: 	cooltabctrl.cpp
	----------------------------------------------------
	Remarks:	...
	----------------------------------------------------

  ####################################################################*/

#include "stdafx.h"
#include "resource.h"
#include "CoolTabCtrl.h"
#include "tools.h"
#include<MMSYSTEM.H>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*####################################################################
			------------------------------------------------
							class CTabPageItem
			------------------------------------------------
  ####################################################################*/
CTabPageItem::CTabPageItem(CCoolTabCtrl* pParentWnd, CWnd* pWnd, 
						   const CString &strText, int nNumber)
{
	m_pParentWnd = pParentWnd;
	m_pWnd = pWnd;
	m_dwState = 0;
	m_strText = strText;
	m_nNumber = nNumber;
	m_hIcon = NULL;
}

CTabPageItem::~CTabPageItem()
{
	if (m_hIcon != NULL)
	{
		DestroyIcon(m_hIcon);
		m_hIcon = NULL;
	}
}

void CTabPageItem::SetIcon(HICON hIcon)
{
	if (m_hIcon != NULL)
	{
		DestroyIcon(m_hIcon);
		m_hIcon = NULL;
	}
	m_hIcon = hIcon;
}

void CTabPageItem::Expend()
{
	m_pWnd->MoveWindow(m_rect);
	m_pWnd->ShowWindow(SW_SHOW);
	m_pWnd->UpdateWindow();
}

void CTabPageItem::SetRect(const CRect &rect)
{
	m_rect = rect;
}

void CTabPageItem::Hide()
{
	m_pWnd->ShowWindow(SW_HIDE);
}


void CTabPageItem::OnDraw(CDC *pDC, int nState)
{
	CRect rect(m_rcLabel);
	switch (m_pParentWnd->m_nMode)
	{
	case TABMODE_NONE:
		break;
	case TABMODE_GROUP:
		{
			pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));
			switch (m_dwState) 
			{
			case 0:	pDC->Draw3dRect(rect, RGB(255,255,255), ::GetSysColor(COLOR_3DSHADOW));
				break;
			case 1:	pDC->Draw3dRect(rect, ::GetSysColor(COLOR_3DFACE), ::GetSysColor(COLOR_3DFACE));
				break;
			}
			pDC->SetBkMode(TRANSPARENT);
			if (m_hIcon != NULL)
			{
				::DrawIconEx( pDC->m_hDC,	rect.left + 3, rect.top + 1, m_hIcon, 16, 16, NULL,	NULL, DI_NORMAL);
			}
			
			pDC->SetTextColor(RGB(0, 0, 0));
			pDC->DrawText(m_strText, rect, DT_CENTER | DT_SINGLELINE |DT_VCENTER);
		}
	break;
	case TABMODE_BOTTOMTAB:
		{
			COLORREF backcolor = ::GetSysColor(COLOR_3DFACE);
			CPen pen(0, 1, AlphaBlendColor(backcolor, 180));
			CPen *oldpen = pDC->SelectObject(&pen);
			
			if (m_nNumber != m_pParentWnd->m_nActivePage)
			{
				rect.DeflateRect(1, 0);
			}
			else
			{
				rect.DeflateRect(-1, -1, -1, 0);
			}

			pDC->MoveTo(rect.left + 2,  rect.bottom);
			pDC->LineTo(rect.right - 1, rect.bottom);
			pDC->MoveTo(rect.left,  rect.top);
			pDC->LineTo(rect.left, rect.bottom - 1);
			pDC->MoveTo(rect.right,  rect.top);
			pDC->LineTo(rect.right, rect.bottom - 1);
			if (m_nNumber == m_pParentWnd->m_nActivePage)
			{
				CRect rc(rect);
				rc.DeflateRect(1, 0, 0, 0);
				FillGradient(pDC, rc, RGB(255, 255, 255), ::GetSysColor(COLOR_3DFACE));
			}
			else
			{
				CRect rc(rect);
				rc.DeflateRect(1, 0, 0, 0);
				FillGradient(pDC, rc, RGB(245, 245, 245), ::GetSysColor(COLOR_3DFACE));
			}
	
			pDC->SetPixel(rect.left + 1, rect.bottom - 1, AlphaBlendColor(backcolor, 180));
			pDC->SetPixel(rect.right - 1, rect.bottom - 1, AlphaBlendColor(backcolor, 180));

			pDC->SelectObject(oldpen);
			
			pDC->SetBkMode(TRANSPARENT);
			if (m_hIcon != NULL)
			{
				::DrawIconEx( pDC->m_hDC,	rect.left + 7, rect.top + 1, m_hIcon, 16, 16, NULL,	NULL, DI_NORMAL);
				rect.left += 18;
			}
			rect.top += 2;
			pDC->SetTextColor(RGB(0, 0, 0));
			pDC->DrawText(m_strText, rect, DT_CENTER | DT_SINGLELINE |DT_VCENTER);
		}
		break;
	case TABMODE_TOPTAB:
		{
			COLORREF backcolor = ::GetSysColor(COLOR_3DFACE);
			CPen pen(0, 1, AlphaBlendColor(backcolor, 180));
			CPen *oldpen = pDC->SelectObject(&pen);
			
			if (m_nNumber != m_pParentWnd->m_nActivePage)
			{
				rect.DeflateRect(1, 0);
			}
			else
			{
				rect.DeflateRect(-1, 0, -1, -1);
			}

			pDC->MoveTo(rect.left + 2,  rect.top);
			pDC->LineTo(rect.right - 1, rect.top);
			pDC->MoveTo(rect.left,  rect.top +2);
			pDC->LineTo(rect.left, rect.bottom);
			pDC->MoveTo(rect.right,  rect.top + 2);
			pDC->LineTo(rect.right, rect.bottom);
			if (m_nNumber == m_pParentWnd->m_nActivePage)
			{
				CRect rc(rect);
				rc.DeflateRect(1, 1, 0, 0);
				FillGradient(pDC, rc, ::GetSysColor(COLOR_3DFACE), RGB(255, 255, 255));
			}
			else
			{
				CRect rc(rect);
				rc.DeflateRect(1, 1, 0, 0);
				FillGradient(pDC, rc, ::GetSysColor(COLOR_3DFACE), RGB(245, 245, 245));
			}
			pDC->SetPixel(rect.left + 1, rect.top + 1, AlphaBlendColor(backcolor, 180));
			pDC->SetPixel(rect.right - 1, rect.top + 1, AlphaBlendColor(backcolor, 180));

			pDC->SelectObject(oldpen);
			
			pDC->SetBkMode(TRANSPARENT);
			if (m_hIcon != NULL)
			{
				::DrawIconEx( pDC->m_hDC,	rect.left + 7, rect.top + 1, m_hIcon, 16, 16, NULL,	NULL, DI_NORMAL);
				rect.left += 18;
			}
			rect.top += 2;
			pDC->SetTextColor(RGB(0, 0, 0));
			pDC->DrawText(m_strText, rect, DT_CENTER | DT_SINGLELINE |DT_VCENTER);
		}
		break;
	default:
		ASSERT(FALSE);
		break;
	}
}

/*#################################################################
						------------------------
							  构建,析构函数
						------------------------
  #################################################################*/

IMPLEMENT_DYNCREATE(CCoolTabCtrl, CWnd)

CCoolTabCtrl::CCoolTabCtrl()
{
	m_nActivePage = 0;
	m_dwStyle = 0;
	m_dwBorderStyle = 0;
	m_nHotItem = 0;
	m_nMode = TABMODE_NONE;
}

CCoolTabCtrl::~CCoolTabCtrl()
{
	int count = m_aTabPage.GetSize();
	for (int i = 0; i < count; i++)
	{
		delete m_aTabPage.GetAt(i);
	}
	m_aTabPage.RemoveAll();
}

BOOL CCoolTabCtrl::Create(const CRect &rect, CWnd *pParentWnd, UINT dwStyle, UINT dwCtrlStyle, UINT nID)
{
	m_dwStyle = dwCtrlStyle;
	
	if (CWnd::Create(AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), (HBRUSH)GetStockObject(LTGRAY_BRUSH), NULL),
				 	 NULL, dwStyle, rect, pParentWnd, nID))
	{
		LOGFONT logFont;
		ZeroMemory((void*)&logFont,sizeof(logFont));
		strcpy(logFont.lfFaceName,"宋体");
		logFont.lfHeight = -12;
		logFont.lfWeight = 400;
		logFont.lfCharSet = GB2312_CHARSET;
		logFont.lfOutPrecision = 3;
		logFont.lfClipPrecision = 2; 
		logFont.lfQuality = 1;
		logFont.lfPitchAndFamily = 2;
		m_fontWnd.CreateFontIndirect(&logFont);
		SetFont(&m_fontWnd);
		return TRUE;
	}
	return FALSE;
}

/*#################################################################
					-------------------------------
							  消息处理函数
					 CCoolTabCtrl message handlers
					-------------------------------
  #################################################################*/

BEGIN_MESSAGE_MAP(CCoolTabCtrl, CWnd)
	//{{AFX_MSG_MAP(CCoolTabCtrl)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_WM_NCPAINT()
	ON_WM_CREATE()
	ON_WM_NCCALCSIZE()
	ON_WM_WINDOWPOSCHANGING()
	ON_WM_NCHITTEST()
	ON_WM_NCLBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_SIZE()
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CCoolTabCtrl::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
}

void CCoolTabCtrl::OnNcPaint()
{
	CWindowDC windc(this); // device context for painting
	int count = m_aTabPage.GetSize();
	
	CRect rcWindow, rcClient;
	GetWindowRect(rcWindow);
    GetClientRect(&rcClient);
	ClientToScreen(&rcClient);
    rcClient.OffsetRect(-rcWindow.TopLeft());
    rcWindow.OffsetRect(-rcWindow.TopLeft());

	if (rcClient.bottom > rcClient.top && rcClient.right > rcClient.left)
	{
		windc.ExcludeClipRect(rcClient);
	}

	CMemDC dc(&windc, rcWindow);
	CFont *oldfont = dc.SelectObject(&m_fontWnd);
	dc.FillSolidRect(rcWindow, ::GetSysColor(COLOR_3DFACE));

	
	switch (m_nMode) 
	{
	case TABMODE_NONE:
		{
			DrawBoder(&dc, rcClient);
		}
		break;
	case TABMODE_GROUP:
		{
			dc.Draw3dRect(rcWindow, RGB(157,157,155), RGB(255,255,255));
		}
		break;
	case TABMODE_BOTTOMTAB:
		{
			DrawBoder(&dc, rcClient);
		}
		break;
	case TABMODE_TOPTAB:
		{
			DrawBoder(&dc, rcClient);
		}
		break;
	default:
		ASSERT(FALSE);
		break;
	}
	
	if (m_nMode != TABMODE_NONE && count > 0)
	{
		for (int i = 0; i < count; i++)
		{
			if (i != m_nActivePage)
			{
				m_aTabPage.GetAt(i)->OnDraw(&dc, 0);
			}
		}
		ASSERT(m_nActivePage >= 0 && m_nActivePage < count);
		if (m_nActivePage >= 0 && m_nActivePage < count)
		{
			m_aTabPage.GetAt(m_nActivePage)->OnDraw(&dc, 0);
		}
	}
	dc.SelectObject(oldfont);
}

BOOL CCoolTabCtrl::OnEraseBkgnd(CDC* pDC) 
{
	CRect rect;
	GetClientRect(rect);
//	pDC->FillSolidRect(rect, RGB(255, 255, 255));
	return TRUE;
}

int CCoolTabCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	return 0;
}

void CCoolTabCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp)
{
	CRect rect(lpncsp->rgrc[0]);
	switch (m_nMode) 
	{
	case TABMODE_NONE:
		rect.DeflateRect(2, 2, 4, 4);
		break;
	case TABMODE_GROUP:
		{
			rect.DeflateRect(1, 1);
			int count = m_aTabPage.GetSize();
			if (count > 0 && m_nActivePage >= 0 && m_nActivePage < count)
			{
				rect.top += (m_nActivePage + 1) * 18;
				rect.bottom -= (count - m_nActivePage - 1) * 18;
			}
		}
		break;
	case TABMODE_BOTTOMTAB:
		rect.DeflateRect(2, 2, 4, 20);
		break;
	case TABMODE_TOPTAB:
		rect.DeflateRect(2, 20, 4, 4);
		break;
	default:
		break;
	}
	lpncsp->rgrc[0] = rect;
}

void CCoolTabCtrl::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) 
{
	lpwndpos->flags |= SWP_FRAMECHANGED;
	CWnd::OnWindowPosChanging(lpwndpos);
}

UINT CCoolTabCtrl::OnNcHitTest(CPoint point) 
{
	return HTCAPTION;
}

void CCoolTabCtrl::OnNcLButtonDown(UINT nHitTest, CPoint point) 
{
	SetCapture();//获得鼠标的输入行为
	
	CRect rcWindow;
	GetWindowRect(rcWindow);
	
	int count = m_aTabPage.GetSize();
	for (int i = 0; i < count; i++)
	{
		CRect rect = m_aTabPage.GetAt(i)->m_rcLabel;
		rect.OffsetRect(rcWindow.TopLeft());
		if (rect.PtInRect(point))
		{
			m_nHotItem = i;
			m_aTabPage.GetAt(i)->m_dwState = 1;
			SendMessage(WM_NCPAINT);
			break;
		}
	}
	PlayResource(IDR_CLICK);//播放声音
}
BOOL CCoolTabCtrl::PlayResource(WORD wResourceID)
{	
	// Get the handle to the current instance of the application
	HINSTANCE hInstance = AfxGetInstanceHandle();
    ASSERT (hInstance != NULL);
	
	// Find the WAVE resource
	HRSRC hResInfo = 
		FindResource(hInstance, MAKEINTRESOURCE(wResourceID), _T("WAVE"));
	if(hResInfo == NULL)
		return FALSE;
	
	// Load the WAVE resource
    HANDLE hRes = LoadResource(hInstance, hResInfo);
	if (hRes == NULL)
		return FALSE;
    
	// Lock the WAVE resource and play it
    LPSTR lpRes = (LPSTR) LockResource(hRes);
	if(lpRes==NULL)
		return FALSE;
    
	if (sndPlaySound(lpRes, SND_MEMORY | SND_ASYNC) == NULL)
		return FALSE;	
	
    // Free the WAVE resource and return success or failure.
    FreeResource(hRes);
	
	return TRUE;
}

void CCoolTabCtrl::OnMouseMove(UINT nFlags, CPoint point) 
{
	ClientToScreen(&point);
	int count = m_aTabPage.GetSize();
	if ((nFlags & VK_LBUTTON) && m_nHotItem >= 0 && m_nHotItem < count)
	{
		CRect rcWindow;
		GetWindowRect(rcWindow);
		
		CRect rect = m_aTabPage.GetAt(m_nHotItem)->m_rcLabel;
		rect.OffsetRect(rcWindow.TopLeft());
		
		UINT state = rect.PtInRect(point) ? 1 : 0;
		if (m_aTabPage.GetAt(m_nHotItem)->m_dwState != state)
		{
			m_aTabPage.GetAt(m_nHotItem)->m_dwState = state;
			SendMessage(WM_NCPAINT);
		}	
	}
	CWnd::OnMouseMove(nFlags, point);
}

void CCoolTabCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
{
	ReleaseCapture();
	int count = m_aTabPage.GetSize();
	if (m_nHotItem >= 0 && m_nHotItem < count)
	{
		ClientToScreen(&point);
		CRect rcWindow;
		GetWindowRect(rcWindow);
		
		CRect rect = m_aTabPage.GetAt(m_nHotItem)->m_rcLabel;
		rect.OffsetRect(rcWindow.TopLeft());
		
		m_aTabPage.GetAt(m_nHotItem)->m_dwState = 0;
		if (rect.PtInRect(point) && m_nHotItem != m_nActivePage)
		{
			SetActivePage(m_nHotItem);
			AutoSize();
		}
		SendMessage(WM_NCPAINT);
	}
	CWnd::OnLButtonUp(nFlags, point);
}

/*#################################################################
					-------------------------------
							控件尺寸处理函数
					  CCoolTabCtrl size handlers
					-------------------------------
  #################################################################*/

void CCoolTabCtrl::AutoSize()
{
	int count = m_aTabPage.GetSize();
	if (count == 0) return;
	
	CTabPageItem* page = NULL;

	if (m_nMode == TABMODE_GROUP && GetSafeHwnd() != NULL)
	{
		//强迫窗口重新计算非客户区大小-----------------------------
		SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE);
	}

	CRect rcWindow, rcClient;
	GetWindowRect(rcWindow);
	GetClientRect(rcClient);
	rcWindow.OffsetRect(-rcWindow.TopLeft());
	
	switch (m_nMode) 
	{
	case TABMODE_NONE:
		{
			for (int i = 0; i < count; i++)
			{
				page = m_aTabPage.GetAt(i);
				if (i != m_nActivePage)
				{
					page->Hide();
				}
				else
				{
					GetClientRect(rcWindow);
					page->SetRect(rcWindow);
					page->Expend();
				}
			}
		}
		break;
	case TABMODE_GROUP:
		{
			rcWindow.DeflateRect(1, 1);
			for (int i = 0; i < count; i++)
			{
				page = m_aTabPage.GetAt(i);
				if (i != m_nActivePage)
				{
					page->m_rcLabel = rcWindow;
					if (m_nActivePage > i)
					{
						page->m_rcLabel.top += (i * 18);
						page->m_rcLabel.bottom = page->m_rcLabel.top + 18;
					}
					else
					{
						page->m_rcLabel.bottom -= 18 * (count - i - 1);
						page->m_rcLabel.top = page->m_rcLabel.bottom - 18;
					}
					page->m_rect = rcClient;
					page->Hide();
				}
				else
				{
					page->m_rcLabel = rcWindow;
					page->m_rcLabel.top += (i * 18);
					page->m_rcLabel.bottom = page->m_rcLabel.top + 18;
					page->m_rect = rcClient;
					page->Expend();
				}
			}
		}
		break;
	case TABMODE_BOTTOMTAB:
		{
			CRect rc(rcWindow);
			rc.right =  1;
			for (int i = 0; i < count; i++)
			{
				page = m_aTabPage.GetAt(i);
				if (i != m_nActivePage)
				{
					page->Hide();
				}
				else
				{
					page->SetRect(rcClient);
					page->Expend();
				}
				rc.top = rc.bottom - 18;
				rc.left = rc.right;
				rc.right = rc.left + 6 * page->m_strText.GetLength() + 10;
				if (page->m_hIcon != NULL) rc.right += 20;
				page->m_rcLabel = rc;
			}
		}
		break;
	case TABMODE_TOPTAB:
		{
			CRect rc(rcWindow);
			rc.right = 1;
			for (int i = 0; i < count; i++)
			{
				page = m_aTabPage.GetAt(i);
				if (i != m_nActivePage)
				{
					page->Hide();
				}
				else
				{
					page->SetRect(rcClient);
					page->Expend();
				}
				rc.bottom = rc.top + 18;
				rc.left = rc.right;
				rc.right = rc.left + 6 * page->m_strText.GetLength() + 10;
				if (page->m_hIcon != NULL) rc.right += 20;
				page->m_rcLabel = rc;
			}
		}
		break;
	default:
		ASSERT(FALSE);
		break;
	}
}

/*#################################################################
					-------------------------------
							控件页面处理函数
					  CCoolTabCtrl page handlers
					-------------------------------
  #################################################################*/

BOOL CCoolTabCtrl::AddPage(CRuntimeClass *pClass, UINT nIDTemplate, LPCTSTR strText, UINT IconID)
{
	CDialog *pDlg = (CDialog*)pClass->CreateObject();
	
	if (pDlg != NULL && pDlg->Create(nIDTemplate, this))
	{
		CTabPageItem *pItem;
		pItem = new CTabPageItem(this, (CWnd*)pDlg, strText, m_aTabPage.GetSize());
		if(IconID != NULL)
		{
			pItem->SetIcon(AfxGetApp()->LoadIcon(IconID));
		}
		m_aTabPage.Add(pItem);

		AutoSize();
		return TRUE;
	}
	return FALSE;
}

BOOL CCoolTabCtrl::AddPage(CWnd *pWnd, LPCTSTR strText, UINT IconID)
{
	if (pWnd != NULL)
	{
		CTabPageItem *pItem;
		pItem = new CTabPageItem(this, pWnd, strText, m_aTabPage.GetSize());
		if(IconID != NULL)
		{
			pItem->SetIcon(AfxGetApp()->LoadIcon(IconID));
		}
		m_aTabPage.Add(pItem);

		AutoSize();
		return TRUE;
	}
	return FALSE;
}

void CCoolTabCtrl::SetCtrlStyle(DWORD dwStyle)
{
	m_dwStyle = dwStyle;
}

void CCoolTabCtrl::SetBorderStyle(DWORD dwStyle)
{
	m_dwBorderStyle = dwStyle;
}

void CCoolTabCtrl::SetActivePage(int nindex)
{
	if (m_nActivePage >= 0 && m_nActivePage < m_aTabPage.GetSize())
	{
		m_nActivePage = nindex;
		AutoSize();
	}
}

void CCoolTabCtrl::SetMode(int nMode)
{
	if (nMode >= 0 && nMode <= TABMODE_BOTTOMTAB)
	{
		m_nMode = nMode;
		if (GetSafeHwnd() != NULL)
		{
			AutoSize();
		}
	}
}

CWnd* CCoolTabCtrl::GetPage(int number)
{
	if (number >= 0 && number < m_aTabPage.GetSize())
	{
		return m_aTabPage.GetAt(number)->m_pWnd;
	}
	return NULL;
}

void CCoolTabCtrl::DrawBoder(CDC *pDC, CRect rect)
{
	COLORREF backcolor = ::GetSysColor(COLOR_3DFACE);
	rect.InflateRect(1, 1);
	pDC->Draw3dRect(rect, RGB(255, 255, 255), RGB(255, 255, 255));
	rect.InflateRect(1, 1);
	pDC->Draw3dRect(rect, AlphaBlendColor(backcolor, 180), AlphaBlendColor(backcolor, 180));
	
	CPen pen(0, 1, AlphaBlendColor(backcolor, 220));
	CPen *oldpen = pDC->SelectObject(&pen);
	pDC->MoveTo(rect.left,rect.bottom);
	pDC->LineTo(rect.right, rect.bottom);
	pDC->MoveTo(rect.right, rect.top);
	pDC->LineTo(rect.right, rect.bottom);
	
	pen.DeleteObject();
	pen.CreatePen(0, 1, AlphaBlendColor(backcolor, 245));
	pDC->SelectObject(&pen);
	pDC->MoveTo(rect.left + 1,rect.bottom + 1);
	pDC->LineTo(rect.right - 1, rect.bottom + 1);
	pDC->MoveTo(rect.right + 1, rect.top + 1);
	pDC->LineTo(rect.right + 1, rect.bottom);
	
	pDC->SelectObject(oldpen);
}



void CCoolTabCtrl::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	
	if (GetSafeHwnd() != NULL)
	{
		AutoSize();
	}
}

void CCoolTabCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CWnd::OnLButtonDown(nFlags, point);
}